//
//  NSMCitySelectorController.m
//  Helper
//
//  Created by nsm on 2019/4/8.
//  Copyright © 2019 nani. All rights reserved.
//

#import "NSMCitySelectorController.h"
#import "NSMCSSearchController.h"
#import "NSMCSSearchHomeController.h"
#import "NSMCSSearchAssociateController.h"

/* 缓存数据 */
static NSString * const kDataCities = @"nsm_cache_data_cities";
/* 历史选择记录 */
static NSString * const kRecentCities = @"nsm_cache_recent_cities";
/* 自定义搜索栏高度 */
const CGFloat kSearchBarH = 44.0f;

@interface NSMCSSectionModel : NSObject
@property (nonatomic) NSMCSMoudle moudle;
@property (nonatomic, copy) NSString *title;
@property (nonatomic, strong) NSArray *dataArray;
@end

@implementation NSMCSSectionModel

@end

@interface NSMCSItemsCell : NSMTableViewCell

@end

@implementation NSMCSItemsCell
- (void)setObject:(NSMCSSectionModel *)model {
    [self.rootLayout removeAllSubviews];
    
    for (CityModel *city in model.dataArray) {
        NSMButton *btn = NSMButton.new;
        btn.backgroundColor = COLOR_4;
        btn.myHeight = 36;
        btn.titleLabel.font = SystemFont(14);
        [btn setTitleColor:COLOR_0 forState:UIControlStateNormal];
        btn.title = SafeString(city.name);
        [self.rootLayout addSubview:btn];
        
        ViewCorner(btn, 5);
        ViewBorder(btn, kSinglePixel*2, SEPARATOR_COLOR);
        
        [btn removeAllTargets];
        @nsm_weak(self)
        [btn addBlockForControlEvents:UIControlEventTouchUpInside block:^(id  _Nonnull sender) {
            @nsm_strong(self)
            !self.actionBlock?:self.actionBlock(city);
        }];
    }
}

- (void)setupSubviews {
    self.contentView.backgroundColor = GROUP_TABLECOLOR;
    
    MyFlowLayout *layout = [MyFlowLayout flowLayoutWithOrientation:MyOrientation_Vert
                                                     arrangedCount:3];
    layout.cacheEstimatedRect = YES;
    layout.myHorzMargin = 0;
    layout.wrapContentHeight = YES;
    layout.gravity = MyGravity_Horz_Fill;
    layout.subviewSpace = 12;
    layout.padding = UIEdgeInsetsMake(0, 15, 0, 15);
    [self.contentView addSubview:layout];
    self.rootLayout = layout;
}

- (void)layoutSubviews {
    [super layoutSubviews];
    
    // 这个地方有BUG需要强制更新layout
    [self.rootLayout setNeedsLayout];
    [self.rootLayout layoutIfNeeded];
}

@end

@interface NSMCSListCell : NSMTableViewCell
@property (nonatomic, strong) UILabel *nameLabel;
@end

@implementation NSMCSListCell
- (void)setObject:(CityModel *)city {
    _nameLabel.text = city.name;
}

- (void)setupSubviews {
    MyLinearLayout *layout = [MyLinearLayout linearLayoutWithOrientation:MyOrientation_Vert];
    layout.backgroundColor = COLOR_4;
    layout.myHorzMargin = 0;
    layout.height = 44;
    layout.wrapContentHeight = NO;
    layout.cacheEstimatedRect = YES;
    layout.padding = UIEdgeInsetsMake(0, 15, 0, 15);
    layout.gravity = MyGravity_Vert_Center;
    [self.contentView addSubview:layout];
    self.rootLayout = layout;
    
    MyBorderline *line = [[MyBorderline alloc] initWithColor:SEPARATOR_COLOR];
    line.headIndent = 15;
    layout.bottomBorderline = line;
    
    UILabel *label = [UILabel new];
    label.wrapContentSize = YES;
    label.font = SystemFont(15);
    label.textColor = COLOR_0;
    [layout addSubview:label];
    _nameLabel = label;
}
@end

@interface NSMCitySelectorController () <UITableViewDataSource>
@property (nonatomic, strong) UISearchController *searchController;
@property (nonatomic, strong) NSArray<NSString *> *indexTitles;
@property (nonatomic, strong) NSMutableArray<NSMCSSectionModel *> *sections;
@property (nonatomic, strong) NSArray<CityModel *> *searchs;

@property (nonatomic, weak) NSMCSSectionModel *recentModel;
@property (nonatomic, weak) NSMCSSectionModel *hotModel;
@property (nonatomic, weak) NSMCSSectionModel *normalModel;
@end

@implementation NSMCitySelectorController

#pragma mark - lifeCycle
+ (instancetype)sharedInstance {
    static NSMCitySelectorController *instance;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [self new];
    });
    return instance;
}

- (void)didInitialize {
    [super didInitialize];
    
    self.ignoreViewDidLayoutSubviews = YES;
}

#pragma mark - override
- (void)viewDidLayoutSubviews {
    [super viewDidLayoutSubviews];
    
    // 自定义搜索栏高度(44)
    if (self.tableView.top != kSearchBarH) {
        CGSize size = self.view.size;
        self.tableView.frame = CGRectMake(0, kSearchBarH, size.width, size.height-kSearchBarH);
    }
}

#pragma mark - initialization
- (void)viewDidLoad {
    [super viewDidLoad];
    
    [self resetData];
    
    @nsm_weak(self)
    BOOL hasCache = [_cacheManager.csCache containsObjectForKey:kDataCities];
    if (hasCache) {
        id data = [_cacheManager.csCache objectForKey:kDataCities];
        [self asyncParseData:data];
    } else {
        NSString *url = @"http://xuehua.test.hbbeisheng.com/api/publics/getCity";
        [_networker POST:url parameters:nil success:^(NSMResponseObject *responseObject) {
            @nsm_strong(self)
            id data = responseObject.data;
            [_cacheManager.csCache setObject:data forKey:kDataCities];
            [self asyncParseData:data];
        } empty:nil failure:nil];
    }
}

- (void)initSubviews {
    [super initSubviews];
    
    [self initNavigationItems];
    [self initSearchBar];
    [self initTableView];
}

- (void)initNavigationItems {
    UIBarButtonItem *closeItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemStop target:self action:@selector(dismissController)];
    self.navigationItem.leftBarButtonItem = closeItem;
}

- (void)initSearchBar {
    MyLinearLayout *layout = [MyLinearLayout linearLayoutWithOrientation:MyOrientation_Vert];
    layout.backgroundColor = UIColor.whiteColor;
    layout.myHorzMargin = 0;
    layout.myHeight = 44;
    // UITableViewIndex宽度
    layout.rightPadding = 27;
    layout.gravity = MyGravity_Center;
    [self.view addSubview:layout];
    
    NSMButton *searchBtn = NSMButton.new;
    searchBtn.backgroundColor = GROUP_TABLECOLOR;
    searchBtn.myHorzMargin = 15;
    searchBtn.height = 32;
    searchBtn.imageSize = CGSizeMake(15, 15);
    searchBtn.spacing = 4;
    searchBtn.tintColor = PLACEHOLDER_TEXT_COLOR;
    searchBtn.adjustsTitleTintColorAutomatically = YES;
    searchBtn.adjustsImageTintColorAutomatically = YES;
    searchBtn.adjustsWhenHighlighted = NO;
    searchBtn.contentEdgeInsets = UIEdgeInsetsMake(0, 8, 0, 0);
    searchBtn.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
    searchBtn.titleLabel.font = CustomFont(14);
    [searchBtn setTitle:(@"城市名") forState:UIControlStateNormal];
    [searchBtn setImage:BundleTemplateImage(@"nsm_search_normal") forState:UIControlStateNormal];
    [searchBtn addTarget:self action:@selector(onBtnClickSearch:) forControlEvents:UIControlEventTouchUpInside];
    ViewCorner(searchBtn, 6);
    [layout addSubview:searchBtn];
}

- (void)initTableView {
    self.tableView.dataSource = self;
    self.tableView.sectionHeaderHeight = 44;
    self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
    self.tableView.sectionIndexColor = SUB_TEXT_COLOR;
    self.tableView.sectionIndexBackgroundColor = COLOR_4;
}

#pragma mark - UITableViewDataSource
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return self.sections.count;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    NSMCSSectionModel *sectionModel = self.sections[section];
    NSInteger count = 0;
    switch (sectionModel.moudle) {
        case NSMCSMoudleNormal:
            count = sectionModel.dataArray.count;
            break;
        default:
            count = sectionModel.dataArray.count?1:0;
            break;
    }
    return count;
}

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
    NSMCSSectionModel *sectionModel = self.sections[section];
    CGFloat height = 0;
    switch (sectionModel.moudle) {
        case NSMCSMoudleNormal:
            height = 40.f;
            break;
        default:
            height = sectionModel.dataArray.count?40.f:0;
            break;
    }
    return height;
}

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
    NSMCSSectionModel *sectionModel = self.sections[section];
    
    UIView *view = UIView.new;
    view.backgroundColor = GROUP_TABLECOLOR;
    
    MyLinearLayout *layout = [MyLinearLayout linearLayoutWithOrientation:MyOrientation_Horz];
    layout.myMargin = 0;
    layout.wrapContentWidth = NO;
    layout.padding = UIEdgeInsetsMake(0, 15, 0, 15);
    layout.gravity = MyGravity_Vert_Center;
    [view addSubview:layout];

    UILabel *label = UILabel.new;
    label.weight = 1;
    label.wrapContentHeight = YES;
    label.numberOfLines = 1;
    label.font = BoldSystemFont(sectionModel.moudle==NSMCSMoudleNormal?16:14);
    label.textColor = COLOR_1;
    label.text = sectionModel.title;
    [layout addSubview:label];
    
    return view;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    NSMCSSectionModel *sectionModel = self.sections[indexPath.section];
    
    NSMTableViewCell *cell;
    switch (sectionModel.moudle) {
        case NSMCSMoudleNormal:
        {
            cell = [NSMCSListCell cell:tableView];
            [cell setObject:sectionModel.dataArray[indexPath.row]];
        }
            break;
        default:
        {
            cell = [NSMCSItemsCell cell:tableView];
            [cell setObject:sectionModel];
            @nsm_weak(self)
            [cell setActionBlock:^(CityModel *city) {
                @nsm_strong(self)
                [self didSelectCity:city];
            }];
        }
            break;
    }
    return cell;
}

- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
    return _indexTitles;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    [tableView deselectRowAtIndexPath:indexPath animated:YES];
    
    NSMCSSectionModel *sectionModel = self.sections[indexPath.section];
    if (sectionModel.moudle != NSMCSMoudleNormal) return;
    
    CityModel *city = sectionModel.dataArray[indexPath.row];
    [self didSelectCity:city];
}

#pragma mark - setter/getter
- (NSString *)titleForMoudle:(NSMCSMoudle)moudle {
    NSDictionary *mapDic = @{@(NSMCSMoudleDistrict) : @"区县",
                             @(NSMCSMoudleSelect)   : @"当前城市",
                             @(NSMCSMoudleCurrent)  : @"定位城市",
                             @(NSMCSMoudleRecent)   : @"最近访问",
                             @(NSMCSMoudleHot)      : @"热门城市"};
    return SafeString(mapDic[@(moudle)]);
}

- (NSArray *)dataForMoudle:(NSMCSMoudle)moudle {
    NSArray *array;
    switch (moudle) {
        case NSMCSMoudleSelect:
            array = @[_amapHelper.selectedCity];
            break;
        case NSMCSMoudleCurrent:
            break;
        case NSMCSMoudleRecent:
            array = SafeArray([_cacheManager.csCache objectForKey:kRecentCities]);
            break;
        default:
            break;
    }
    return array;
}

#pragma mark - network
- (void)asyncParseData:(id)data {
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        [self parseData:data];
        dispatch_async(dispatch_get_main_queue(), ^{
            [self.tableView reloadData];
        });
    });
}

- (void)parseData:(id)data {
    // 1.解析热门城市
    NSArray *hots = [NSArray modelArrayWithClass:CityModel.class json:data[@"hot"]];
    for (NSMCSSectionModel *sectionModel in _sections) {
        if (sectionModel.moudle == NSMCSMoudleHot) {
            sectionModel.dataArray = hots;
            break;
        }
    }
    // 2.解析城市列表
    [self sortListData:data[@"list"]];
    
    // 3.重置标题索引
    [self resetIndexTitles];
}

- (void)sortListData:(NSArray *)lists {
    _searchs = [NSArray modelArrayWithClass:CityModel.class json:lists];
    
    NSMutableDictionary *tempDic = @{}.mutableCopy;
    for (CityModel *model in _searchs) {
        NSString *character = model.pinYin;
        if (!character.length) {
            // 这个很耗时,优先接口返回pinyin字段
            character = [NSMCharacterManager chineseToPinYin:model.name];
        }
        NSString *firstLetter = [character substringToIndex:1].uppercaseString;
        NSMutableArray *values = tempDic[firstLetter];
        if (values)
            [values addObject:model];
        else {
            // 是否以字母开头
            BOOL isBeginWithLetter = [firstLetter regex:NSMRegexBeginWithLetter];
            if (!isBeginWithLetter) {
                if (tempDic[@"#"]) {
                    values = tempDic[@"#"];
                    [values addObject:model];
                } else {
                    firstLetter = @"#";
                    values = @[model].mutableCopy;
                    tempDic[firstLetter] = values;
                }
            } else {
                values = @[model].mutableCopy;
                tempDic[firstLetter] = values;
            }
        }
    }
    
    // 索引下标排序
    NSArray *sortedArray = [tempDic.allKeys sortedArrayUsingSelector:@selector(compare:)];
    if (!sortedArray.count) return;
    
    NSMutableArray *indexTitles = sortedArray.mutableCopy;
    // 将"#"放到最后("#"排序比字母靠前)
    BOOL isLetter = [sortedArray.firstObject regex:NSMRegexBeginWithLetter];
    if (!isLetter) {
        NSString *firstLetter = indexTitles.firstObject;
        [indexTitles removeObjectAtIndex:0];
        [indexTitles addObject:firstLetter];
    }
    
    // 按索引拼接数据
    for (NSString *title in indexTitles) {
        NSMCSSectionModel *model = NSMCSSectionModel.new;
        model.moudle = NSMCSMoudleNormal;
        model.title = title;
        model.dataArray = tempDic[title];
        [_sections addObject:model];
    }
}

#pragma mark - method/public

#pragma mark - method/private
- (void)resetData {
    _sections = @[].mutableCopy;
    for (NSNumber *value in _moudles) {
        NSMCSMoudle moudle = value.integerValue;
        NSMCSSectionModel *model = NSMCSSectionModel.new;
        model.moudle = moudle;
        model.title = [self titleForMoudle:moudle];
        model.dataArray = [self dataForMoudle:moudle];
        [_sections addObject:model];
        
        switch (moudle) {
            case NSMCSMoudleRecent:
                _recentModel = model;
                break;
            case NSMCSMoudleHot:
                _hotModel = model;
                break;
            case NSMCSMoudleNormal:
                _normalModel = model;
                break;
            default:
                break;
        }
    }
    
    [self resetIndexTitles];
}

- (void)resetIndexTitles {
    NSMutableArray *titles = @[].mutableCopy;
    for (NSMCSSectionModel *model in _sections) {
        if (model.dataArray.count) {
            NSString *title = [model.title substringToIndex:MIN(2, model.title.length)];
            [titles addObject:title];
        }
    }
    _indexTitles = titles;
}

- (void)updateRecentCities:(CityModel *)city {
    // 去除重复的
    NSArray *orgArray = _recentModel.dataArray;
    NSMutableArray *copyArray = [NSMutableArray arrayWithArray:orgArray];
    for (CityModel *obj in orgArray) {
        if ([obj.cid isEqualToString:city.cid]) {
            [copyArray removeObject:obj];
        }
    }
    // 新的记录排前面
    [copyArray insertObject:city atIndex:0];
    
    // 得到最终的新数组(最多保持3条记录)
    NSArray *cutArray = [copyArray subarrayWithRange:NSMakeRange(0, MIN(3, copyArray.count))];
    // 此处可以不刷新.反正模态视图消失了用户看不到
    [self.tableView reloadData];
    
    // 保存起来
    _recentModel.dataArray = cutArray;
    [_cacheManager.csCache setObject:cutArray forKey:kRecentCities];
}

- (void)didSelectCity:(CityModel *)city {
    _amapHelper.selectedCity = city;
    // 更新最近访问城市
    [self updateRecentCities:city];
    // 通知其他模块
    !self.didSelectCity?:self.didSelectCity(city);
    // 退出模态
    [self dismissViewControllerAnimated:YES completion:nil];
}

#pragma mark - action
- (void)onBtnClickSearch:(NSMButton *)sender {
    NSMCSSearchHomeController *home = NSMCSSearchHomeController.new;
    NSMCSSearchAssociateController *associate = NSMCSSearchAssociateController.new;
    associate.searchs = self.searchs.copy;
    
    NSMCSSearchController *search = NSMCSSearchController.new;
    search.homeController = home;
    search.associateController = associate;
    
    NSMNavigationController *nav = [NSMNavigationController controller:search];
    nav.modalPresentationStyle = UIModalPresentationFullScreen;
    @nsm_weak(self)
    @nsm_weak(nav)
    associate.didSelectAssociateItem = ^(CityModel *obj) {
        @nsm_strong(self)
        @nsm_strong(nav)
        [nav dismissViewControllerAnimated:NO completion:^{
            [self didSelectCity:obj];
        }];
    };
    [self presentViewController:nav animated:NO completion:nil];
}

- (void)dismissController {
    [self dismissViewControllerAnimated:YES completion:nil];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
}

@end
